/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package elaborate.tag_analysis.client.actions.closeness_centrality;

import elaborate.tag_analysis.client.graph.Graph;
import elaborate.tag_analysis.client.graph.SimpleSparseGraph;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *
 * @author lendle
 */
public class ClosenessCentralityCalc {
    public double [] calculate(Graph g){
        List points=g.getPoints();
        double [] values=new double[points.size()];
        for(int i=0; i<values.length; i++){
            values[i]=this.calculate(points.get(i), g);
        }
        return values;
    }
    public double calculate(Object point, Graph g){
        List points=g.getPoints();
        double distanceSum=0;
        int currentDistance=0;
        List currentStartPoints=new ArrayList();
        currentStartPoints.add(point);
        Map<Object, String> visitedMap=new HashMap<Object, String>();
        visitedMap.put(point, "");
        
        while(currentStartPoints.isEmpty()==false){
            Object currentStartPoint=currentStartPoints.remove(0);
            for(Object target : points){
                if(target.equals(point) || visitedMap.containsKey(target)){
                    continue;
                }
                if(g.isConnected(currentStartPoint, target)){
                    distanceSum+=(currentDistance+1);
                    visitedMap.put(target, "");
                    currentStartPoints.add(target);
                }
            }
            currentDistance++;
        }
        return (points.size()-1)/distanceSum;
    }
    
    public static void main(String [] args) throws Exception{
        SimpleSparseGraph g=new SimpleSparseGraph();
        g.setDirected(false);
        g.addPoint("A");
        g.addPoint("B");
        g.addPoint("C");
        g.addPoint("D");
        g.setConnected("A", "B");
        g.setConnected("B", "C");
        g.setConnected("B", "D");
        g.setConnected("D", "C");
        g.setConnected("A", "C");
        
        for(int i=0; i<1000; i++){
            g.addPoint("Point_"+i);
        }
        
        for(int i=0; i<g.getPoints().size(); i++){
            for(int i1=0; i1<g.getPoints().size(); i1++){
                if(i!=i1){
                    double test=Math.random();
                    if(test>=0.9){
                        //System.out.println("connected "+test+" "+"Point_"+i+" to "+"Point_"+i1);
                        g.setConnected("Point_"+i, "Point_"+i1);
                    }
                    
                }
            }
        }
        System.out.println("start calculate");
        long startTime=System.currentTimeMillis();
        ClosenessCentralityCalc calc=new ClosenessCentralityCalc();
        //System.out.println(calc.calculate("A", g));
        double [] values=calc.calculate(g);
        long okTime=System.currentTimeMillis();
        for(double value : values){
            System.out.println(value);
        }
        System.out.println(okTime-startTime);
    }
}
